﻿Imports Runa.Foundation.Messaging
Imports Runa.Core.Services
Imports Runa.Foundation.Threading

Partial Public Class GameRender
    Implements IMessageFilter

    Public Function DispachMessage(ByRef m As Message) As Boolean Implements IMessageFilter.DispachMessage, ISafeNativeMethods.DispachMessage
        If m.IsInputMessage Then
            m.Result = True
            Dim collection = Me.Hwnds.Skip(2).ToList()
            For Each hwnd In collection
                If CType(hwnd, IMessageFilter).WndProc(m) Then
                    m.Result = DirectCast(m.Result, Boolean) And True
                End If
            Next
            Return DirectCast(m.Result, Boolean)
        ElseIf m.HWnd Is Nothing Then
            If Me.RootFrame IsNot Nothing Then
                If Me.RootFrame.WndProc(m) = False Then
                    Return Me.WndProc(m)
                End If
            End If
        ElseIf TypeOf m.HWnd Is IMessageFilter Then
            Return CType(m.HWnd, IMessageFilter).WndProc(m)
        Else
            For Each hwnd In Me.Hwnds
                If hwnd.Equals(m.HWnd) Then
                    If CType(hwnd, IMessageFilter).WndProc(m) Then
                        m.Result = DirectCast(m.Result, Boolean) And True
                        Return DirectCast(m.Result, Boolean)
                    End If
                End If
            Next
        End If
        Return True
    End Function

    Public Function GetMessage(ByRef m As Runa.Foundation.Messaging.Message, ByVal tid As Integer) As Boolean Implements ISafeNativeMethods.GetMessage
        Return ThreadPool.GetMessage(m, tid)
    End Function

    Public Function PeekMessage(ByRef m As Runa.Foundation.Messaging.Message, ByVal tid As Integer, ByVal removeMessage As Boolean) As Boolean Implements ISafeNativeMethods.PeekMessage
        Return ThreadPool.PeekMessage(m, tid, removeMessage)
    End Function

    Public Function PostMessage(ByVal tid As Integer, ByVal m As Runa.Foundation.Messaging.Message) As Boolean Implements ISafeNativeMethods.PostMessage
        Return ThreadPool.PostMessage(tid, m)
    End Function

    Public Function SendMessage(ByVal tid As Integer, ByVal m As Runa.Foundation.Messaging.Message) As Boolean Implements ISafeNativeMethods.SendMessage
        Return ThreadPool.SendMessage(tid, m)
    End Function

    Public Function GetQueueStatus(flag As UInteger) As UInteger Implements ISafeNativeMethods.GetQueueStatus
        Return ThreadPool.GetQueueStatus(flag)
    End Function

    Public Function GetMessage(ByRef m As Message, tid As Integer, from As MessageType, [to] As MessageType) As Boolean Implements ISafeNativeMethods.GetMessage
        Return ThreadPool.GetMessage(m, tid, from, [to])
    End Function

    Public Function PeekMessage(ByRef m As Message, tid As Integer, from As MessageType, [to] As MessageType, removeMessage As Boolean) As Boolean Implements ISafeNativeMethods.PeekMessage
        Return ThreadPool.PeekMessage(m, tid, [from], [to], removeMessage)
    End Function

    Public Function PostMessage(m As Message) As Boolean Implements ISafeNativeMethods.PostMessage
        Return Me.PostMessage(Thread.CurrentThread.ThreadID, m)
    End Function

    Public Function SendMessage(m As Message) As Boolean Implements ISafeNativeMethods.SendMessage
        Return Me.SendMessage(Thread.CurrentThread.ThreadID, m)
    End Function

    Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        ' ToDo: Add support of delegate message.
        Return False
    End Function

    Public Function TranslateMessage(ByRef m As Message) As Boolean Implements IMessageFilter.TranslateMessage, ISafeNativeMethods.TranslateMessage
        If Me.MessageHandlers.ContainsValue(m.Message) Then
            Dim msg = m.Message
            m.Result = Me.MessageHandlers.First(Function(item) item.Value = msg).Key
            Return True
        Else
            Return False
        End If
    End Function

    Public Function WndProc(ByRef m As Message) As Boolean Implements IMessageFilter.WndProc
        Dim flag = TranslateMessage(m)
        Dim bHandled = PreFilterMessage(m)
        If bHandled = False Then
            flag = flag And DispachMessage(m)
        End If
        Return flag
    End Function

End Class